package com.mrx.xfriendship.service;

import com.alibaba.fastjson.JSONObject;
import com.mrx.commons.config.RedisConstant;
import com.mrx.commons.exception.BusinessException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.Optional;

/**
 * redis 相关服务接口
 *
 * @author : 肖康宁
 * @since : 2022-12-09 09:59
 **/
public interface IRedisService {

    /**
     * 向 redis 中存放一个 name->token 的键值对<br/>
     * 该 token 有一个默认的过期时间是 {@link RedisConstant#DEFAULT_TOKEN_TTL} 分钟
     *
     * @param name  用户名
     * @param token 用户 token
     */
    void setUserToken(String name, String token);

    /**
     * 向 redis 中存放一个 name->token 的键值对 并手动设置过期时间, 单位 分钟
     *
     * @param name    用户名
     * @param token   用户 token
     * @param timeout token 过期时间 ( 分钟 )
     */
    void setUserToken(String name, String token, long timeout);

    /**
     * 通过 用户名 查找 redis 中存放的 token<br/>
     * 获取 token 后会对其进行 续期 操作
     *
     * @param name 用户名
     */
    @NonNull
    String getUserToken(String name) throws BusinessException;

    /**
     * 将验证码 key 和 验证码 value 绑定
     *
     * @param key   验证码 key
     * @param value 验证码 value
     */
    void setCaptcha(String key, String value);

    /**
     * 获取指定 key 的 正确的 验证码, ( 如果找不到将返回 null ) 并删除其 kv 映射<br/>
     * 若调用本方法之后未重新调用 {@link #setCaptcha(String, String)}<br/>
     * 第二次再以相同的 key 调用本方法将返回 null
     *
     * @param key 验证码 key
     * @return 正确的验证码
     */
    @Nullable
    String getCaptcha(String key);

    /**
     * 删除指定用户的 token
     *
     * @param userName 用户名
     */
    void removeUserToken(String userName);

    /**
     * 记录 来自 location 的 pv
     *
     * @param location 流量来源
     */
    void plusSitePV(String location);

    /**
     * 获取当前缓存的 pv 数据
     *
     * @param delete 获取后是否删除, true 将会删除
     * @return 当前缓存的 pv 数据
     */
    @Nullable
    JSONObject getSitePvList(boolean delete);

    /**
     * 设置指定 post 的 pv 自增 1
     *
     * @param postId postId
     */
    void plusPostPV(Integer postId);

    Integer getPostPV(Integer postId);

    /**
     * 获取指定 post 的 pv
     *
     * @param isSync 是否为 定时任务获取, 如果是, 获取完后会删除 key
     * @return post 的 pv 增量
     */
    @Nullable
    JSONObject getPostPVList(boolean isSync);

    void plusOnlineUser(Integer currentUserId);

    void minusOnlineUser(Integer currentUserId);

    @NonNull
    Integer getOnlineUser();

    /**
     * 设置 绑定邮箱的 缓存, 10 分钟后将会失效
     *
     * @param userName 用户名
     * @param value    value
     */
    void setBindMail(String userName, String value);

    Optional<String> getBindMail(String userName);

    Boolean setRateLimiter(String key, Integer timeout);

    Optional<Long> getRateLimiter(String key);

}
